正如第一篇文章所說的 Flutter 是一個「框架」,可以用來開發跨平台原生的應用程式。
整個 Flutter的架構圖:
由上到下分別是框架層、引擎層、嵌入層
從最下面兩層的 Animation、Painting、Gestures 及Foundation結合起來就 dart:ui
這個library,這層提供了基本常用的抽象API像是:繪製畫面、動畫、輸入等等。所以這層其實也就是直接操作引擎畫面中哪個pixel要繪製什麼、這動畫會要往哪個方向移動幾pixel之類非常基礎的操作。
Rendering層也就是RenderObject Tree所在的地方,在這層會利用 RenderObjects
來協助畫面的更新、渲染等等當我們動態的更新資料時,這層會幫我計算我們所需要重新繪製的部分然後重新渲然,而我們不用直接呼叫dart:ui
相關的api。
Widgets層則是提供一些基本常用widget,並在此基礎提供了 Material 及 Cupertino 這兩個設計規範的widget。
是用純C++實作的SDK,透過SKIA引擎將真正的繪製邏輯實作在這層,而dart:ui
最終則是調用這層的API
而嵌入層則是將flutter安裝到各大平台的嵌入器,而這個嵌入器是會根據不同平台而使用不同的程式語言實作,像是Android會用JAVA、iOS用Objective-C。但這個嵌入器除了看是安裝整個flutter app 也可以把flutter code 變成module嵌入其他已經用其他原生語言開發的專案。
這邊只是讓各位讀者整個Flutter有點初步的印象,實際上開發時應該是都聚焦在框架層,而且也當你需要了解一些進階的問題時才會認真的去看這些層幫我們做了什麼事,像是想要知道 key
到底做了什麼事、狀態更新時哪些東西會被銷毀或重新建立之類的問題。
在官方文件裡有寫到 Flutter 到底運用了哪些概念
我個人認為有幾點特別重要
UI = F(state) 其實就是Reactive programming加上Declarative programming的概念,我的畫面是根據「狀態」變更而響應式的去重新繪製畫面,而且我不用去管要如何重新繪製,我只要知道他要變更什麼。
我只要將我需要動態變更的資料放進widget裡,資料變更時他自然就會重新繪製,當然還需要一個一個有辦法「反應」資料變化的東西存在,可能是state本身、observer等等之類。
Text('${someAPIData.filed1}',style:textStyle)
簡而言之,我們不需要在變更資料後還要手動去trigger UI的re-render。
在 Flutter 中所有的有關顯示的東西都是widget,容器(像是container)是widget、按鈕是widget、layout相關(像是padding之類)也是widget,而且也可以像react一樣,我們可以藉由拆分components(widgets)來建構我們的應用程式。
widget 也是一種 immutable的 UI 宣告方式,意思是我們的widget本身其實immutable,他建立完之後就是不可變的,這也就是為什麼所有widget為什麼都是要用 final
來宣告參數,以及為什麼 StatefulWidget
的build()
是放在 State
而不是 StatefulWidget
本身的class裡面。
但需要這樣設計的詳細原因等到之後有機會再說,這邊稍微說一下我們實際看到渲染出來的不是widget而是rednerObject。
承上面所說在Flutter中每個小功能都是一個widget,所以當我們想要padding 我們就用 Padding
包住現有的 widget ,想要手勢操作就用 GestureDetector
。講白一點我們把可設定的屬性都拆成各個widget然後我們再自己層層架構。
但這樣做的好處是什麼?我們需要什麼就拿什麼,不用去管哪個widget只有開哪些參數。
但壞處也很明顯就是我們的程式碼的巢狀結構會十分十分的深,這點也是許多人詬病flutter的一點,畢竟不像是寫網頁那樣我可能是一個 div
就已經將間距、顏色、資料綁定、事件監聽都給通通結合在一起了,當然會在不同地方實作這些需求,但至少這個div
在 jsx
or 其他樣板引擎應該都只是一層tag而已。
但一些真的很常用的參數其實還是可以在 Container
這個widget一起做掉像是 alignment
、 padding
、 width
、 hight
等等屬性。至於這樣子到底有沒有跟aggressive composition這個理念衝突我覺得這是 flutter 保留的彈性,如果我真的一次要設定那麼多屬性那就直接在Container
設定就好,如果只要設定padding 那我可能就wrap Padding
就好
今天終於開始進入 Flutter 的篇章,明天開始我們就要建立第一個 Flutter 專案。
參考資料